home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_46 / sbdac.c < prev    next >
C/C++ Source or Header  |  1995-01-01  |  3KB  |  125 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include "sb.h"
  4.  
  5. static void far interrupt (*OldIRQ)();
  6. static volatile int DMA_complete;
  7. static int high_speed = 0;
  8.  
  9. /* Interrupt handler for DMA complete IRQ from Soundblaster */
  10. static void far interrupt SBHandler()
  11. {
  12.     enable();
  13.     DMA_complete = 1;
  14.  
  15.     /* Acknowledge the interrupt */
  16.     inportb(DSP_DATA_AVAIL);
  17.     outportb(0x20,0x20);
  18. }
  19.  
  20. /* Sets the sample rate to be used for digitising or playback */
  21. unsigned Sb_Sample_Rate(unsigned rate, int direction)
  22. {
  23.     unsigned char tc;
  24.  
  25.     tc = (unsigned char) (256 - ((1000000L + rate/2)/rate));
  26.     /* Determine the actual sampling rate */
  27.     rate = (unsigned) (1000000L / (256 - tc));
  28.     /* Do we need to select high-speed mode? */
  29.     high_speed = (rate > (direction == PLAY ? MAX_LO_PLAY : MAX_LO_REC));
  30.  
  31.     writedac(TIME_CONSTANT);  /* Command byte for sample rate */
  32.     writedac(tc);    /* Sample rate time constant */
  33.     return rate;
  34. }
  35.  
  36. void Sb_Voice(int state)
  37. {
  38.     writedac((state) ? SPEAKER_ON : SPEAKER_OFF);
  39. }
  40.  
  41. void Sb_Voice_DMA(char far *data, unsigned dlen, int stereo, int direction)
  42. {
  43.     unsigned char im, tm;
  44.  
  45.     DMA_complete = 0;
  46.     dlen--;  /* SB and DMA controller require number of bytes minus 1 */
  47.  
  48.     /* Enable interrupts on PIC */
  49.     im = inportb(0x21);
  50.     tm = ~(1 << SbIRQ);
  51.     outportb(0x21,im & tm);
  52.     enable();
  53.  
  54.     /* Setup DMA */
  55.     prevent_dma(SbDMAchan);
  56.     dma_setup(SbDMAchan,data,dlen,direction);
  57.  
  58.     /* Turn on stereo output */
  59.     if(stereo && SbType == SBPro && direction == PLAY)
  60.     writemixer(0x0e,0x13);
  61.  
  62.     /* Start the Soundblaster */
  63.     if (high_speed) {
  64.         writedac(SET_HS_SIZE);
  65.         writedac(dlen & 0xff);
  66.         writedac(dlen >> 8);
  67.         writedac(direction == PLAY ? HS_DAC : HS_ADC);
  68.     } else {
  69.         writedac(direction == PLAY ? DMA_8_BIT_DAC : DMA_ADC);
  70.         writedac(dlen & 0xff);
  71.         writedac(dlen >> 8);
  72.     }
  73. }
  74.  
  75. void Sb_Init_Voice_DMA(void interrupt (*handler)(void))
  76. {
  77.     /* Insert our IRQ handler into interrupt chain */
  78.     disable();
  79.     OldIRQ = getvect(0x08 + SbIRQ);
  80.     if(!handler)
  81.         handler = SBHandler;
  82.  
  83.     setvect(0x08 + SbIRQ,handler);
  84.     enable();
  85. }
  86.  
  87. void Sb_DeInit_Voice_DMA(void)
  88. {
  89.     unsigned char tm;
  90.  
  91.     /* Turn off stereo output */
  92.     if(SbType == SBPro)
  93.     writemixer(0x0e,0x11);
  94.  
  95.     /* Restore old IRQ vector */
  96.     disable();
  97.     setvect(0x08 + SbIRQ,OldIRQ);
  98.     tm = inportb(0x21);
  99.     outportb(0x21,tm | (1 << SbIRQ));
  100.     enable();
  101. }
  102.  
  103. int Sb_DMA_Complete(void)
  104. {
  105.     return DMA_complete;
  106. }
  107.  
  108. void Sb_Halt_DMA(void)
  109. {
  110.     if (high_speed) {
  111.         prevent_dma(SbDMAchan);
  112.     } else {
  113.         writedac(HALT_DMA);
  114.     }
  115. }
  116.  
  117. void Sb_Continue_DMA(void)
  118. {
  119.     if (high_speed) {
  120.         allow_dma(SbDMAchan);
  121.     } else {
  122.         writedac(CONTINUE_DMA);
  123.     }
  124. }
  125.